﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        //public delegate void LoggerDelegate(String text);
        public Logger.LoggerDelegate loggerDelegate;

        public Form1()
        {
            InitializeComponent();
            loggerDelegate = new Logger.LoggerDelegate(log);
            Logger.getInstance().setDelegate(loggerDelegate);
        }

        private void log(String text) {
            const int MAX_LOG_LINE = 500;
            String tmp;
            String[] lines = logTextBox.Text.Trim().Split(new char[] { '\n' });
            if (lines[lines.Length-1].Equals(text)) {
                return;
            }
            if (lines.Length >= MAX_LOG_LINE)
            {
                tmp = logTextBox.Text.Substring(logTextBox.Text.IndexOf('\n') + 1);
            }
            else
            {
                tmp = logTextBox.Text;
            }
            logTextBox.Text = tmp + text + '\n'; 

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            ckf = new bool[checkedListBox1.Items.Count];
            for (int i = 0; i < checkedListBox1.Items.Count; i++)
            {
                ckf[i] = false;
            }
            pc = new PrivateController();
            pc.setProcess("魔兽世界");
            resetProcess();
            sc = new ScreenCapturer();

            comboBox1.Items.Clear();
            comboBox1.Items.AddRange(sc.srlib.Keys.ToArray());

            string mastery = Properties.Settings.Default.Mastery;
            if (mastery != null && !mastery.Equals("") && sc.srlib.Keys.Contains(mastery))
            {
                comboBox1.Text = mastery;
            }
            else
            {
                comboBox1.Text = comboBox1.Items[0].ToString();
            }

            textBox1.Text = Properties.Settings.Default["Step"].ToString();
            step = int.Parse(textBox1.Text);
            comboBox2.Text = Properties.Settings.Default.Preset;
            //pc.press((char)VirtualKeys.VK_RETURN);
            //Thread.Sleep(3000);
            //pc.mousedown(87,549);
            //pc.mousedown(268 + 32 + 2 + 1, 81);
            //pc.mousedown(268 + 32 + 2 + 1, 81);
            //
            /*
            pc.press((char)VirtualKeys.VK_RETURN);
            pc.press((char)VirtualKeys.VK_DIVIDE);
            pc.press((char)VirtualKeys.VK_T);
            pc.press((char)VirtualKeys.VK_A);
            pc.press((char)VirtualKeys.VK_R);
            pc.press((char)VirtualKeys.VK_G);
            pc.press((char)VirtualKeys.VK_E);
            pc.press((char)VirtualKeys.VK_T);
            pc.press((char)' ');
            pc.press((char)VirtualKeys.VK_R);
            pc.press((char)VirtualKeys.VK_R);
            pc.press((char)VirtualKeys.VK_R);
            pc.press((char)VirtualKeys.VK_R);
            pc.press((char)VirtualKeys.VK_NUM1);
            pc.press((char)VirtualKeys.VK_RETURN);
             * */
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (updateThread != null)
            {
                return;
            }
            resetProcess();

            updateThread = new Thread(updateMethod);
            statusLabel.Text = "Running";
            updateThread.Start();
        }


       // private double delaystart;
        private void updateMethod() {
            try
            {
                while (true)
                {
                    comboBox1.Text = sc.selectedMastery;
                    for (int k = 0; k < checkedListBox1.Items.Count; k++)
                    {
                        ckf[k] = checkedListBox1.GetItemChecked(k);
                    }

                    string error;
                    SpellInfo spell = sc.run(pc.target,comboBox2.Text,out error);
                    short altstat = pc.GetVirtualKeyState(VirtualKeys.VK_MENU);
                    short ctrlstat = pc.GetVirtualKeyState(VirtualKeys.VK_CONTROL);

                    if (spell != null && spell.key == 0)
                    {
                        spell = null;
                    }


                    VirtualKeys[] keys = { VirtualKeys.VK_NUM1 , VirtualKeys.VK_NUM2 , VirtualKeys.VK_NUM3 , VirtualKeys.VK_V,VirtualKeys.VK_T, VirtualKeys.VK_C, VirtualKeys.VK_R};
                    bool ready = true;
                    foreach (VirtualKeys k in keys)
                    {
                        if (pc.GetVirtualKeyState(k) <= -127)
                        {
                            ready = false;
                        }
                    }

                    //pc.press('0');
                    //pc.press('8');
                    int stopcorrection = step;
                    if (spell != null && altstat > -127 && ready)
                    {
                        if (ctrlstat > -127)
                        {
                            if (spell.target <= 40 && spell.target >= 0)
                            {
                                //pc.press((int)VirtualKeys.VK_LBUTTON);
                                //pc.mousedown();
                                int i, j;
                                if (spell.target == 0)
                                {
                                    i = 9; j = 1;
                                }
                                else
                                {
                                    i = (int)Math.Floor((double)(spell.target - 1) / 5.0);
                                    j = spell.target - 1 - i * 5;
                                }
                                pc.mousedown(268 + 32 + 2 + 1 + j, 81 + i);
                                pc.mousedown(268 + 32 + 2 + 1 + j, 81 + i);
                                pc.mousedown(268 + 32 + 2 + 1 + j, 81 + i);
                            }
                            else
                            { if (spell.stopcasting)
                                {
                                    if (sc.stopcastingspell != null)
                                    {
                                        pc.press(sc.stopcastingspell.key);
                                    }
                                    else
                                    {
                                        pc.press(121);
                                    }
                                    stopcorrection = 50;
                                }
                                else {
                                    pc.press(spell.key);
									Logger.log("Key " + spell.key + " Down");
								}
                            }
                        }
                        else
                        {
                            Logger.log("Stop. Ctrl Down");
                        }
                        for (int j = 0; j < checkedListBox1.Items.Count; j++)
                        {
                            if (ckf[j])
                            {
                                pc.press((int)VirtualKeys.VK_F1 + j);
                            }
                        }
                    }
                    else
                    {
                        if (spell == null)
                        {
                            Logger.log("Stop. " + error);
                        }
                        else if (altstat <= -127)
                        {
                            Logger.log("Stop. " + "Alt Down");
                        }
                        else if (!ready)
                        {
                            Logger.log("Stop. " + "User Key Down");
                        }
                    }

                    Thread.Sleep(step + new Random().Next((int)(step / 5)) - (int)(step / 10));
                }
            }
            catch (Exception)
            {
                updateThread = null;
                statusLabel.Text = "Stopped";
                return;
            }
        }

        private void trainMethod()
        {
            try
            {
                while (true)
                {
                    sc.trainingSpells(pc.target,comboBox2.Text);
                }
            }
            catch (Exception)
            {
                updateThread = null;
                statusLabel.Text = "Stopped";
                return;
            }
        }

        PrivateController pc;
        ScreenCapturer sc;
        Thread updateThread;
        bool[] ckf;

        private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (updateThread != null)
            {
                updateThread.Abort();
            }
            updateThread = null;
            statusLabel.Text = "Stopped";
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            sc.selectedMastery = comboBox1.SelectedItem.ToString();
            Properties.Settings.Default.Mastery = sc.selectedMastery;
            Properties.Settings.Default.Save();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (updateThread != null)
            {
                return;
            }
            resetProcess();

            updateThread = new Thread(trainMethod);
            statusLabel.Text = "Training";
            updateThread.Start();
        }

        private void button4_Click(object sender, EventArgs e)
        {

            if (updateThread != null)
            {
                updateThread.Abort();
            }
            updateThread = null;

            sc.clearTrainingHistory();
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (updateThread != null)
            {
                textBox1.Text = Properties.Settings.Default["Step"].ToString();
                return;
            }
            int result;
            if (int.TryParse(textBox1.Text, out result) && result > 0)
            {
                Properties.Settings.Default["Step"] = result;
                Properties.Settings.Default.Save();
                step = result;
            }
        }
        private int step;

        private void statusLabel_TextChanged(object sender, EventArgs e)
        {
            if (statusLabel.Text.Equals("Stopped"))
            {
                textBox1.Enabled = true;
            }
            else
            {
                textBox1.Enabled = false;
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {

            if (updateThread != null)
            {
                updateThread.Abort();
            }
            updateThread = null;
        }


        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.Preset = comboBox2.Text;
            Properties.Settings.Default.Save();
        }

        private void resetProcess()
        {

            pc.setProcess("魔兽世界");
            comboBox3.Items.Clear();
            for (int i = 0; i < pc.targetList.Count; i++)
            {
                comboBox3.Items.Add(pc.targetList[i]);
            }
            if (pc.target != IntPtr.Zero && comboBox3.Items.Contains(pc.target))
            {
                comboBox3.SelectedItem = pc.target;
            }
            else if (comboBox3.Items.Count > 0)
            {
                comboBox3.SelectedIndex = 0;
            }
            if (pc.targetList.Count > 0)
            {
                pc.target = (IntPtr)comboBox3.SelectedItem;
            }
            else
            {
                pc.target = IntPtr.Zero;
            }
        }

        static int interactcount = 0;
        private void xiaoyiMethod()
        {
            try
            {
                resetProcess();
                while (true)
                {
                    string error;
                    SpellInfo si = sc.run(pc.target, "HEDD", out error);
                    if (si != null)
                    {
                        interactcount++;
                    }
                    else
                    {
                        interactcount = 0;
                    }

                    pc.press(118);
                    //pc.press(118);
                    //Thread.Sleep(200);
                    if (interactcount >= 3)
                    {
                        pc.press(119);
                    }

                    Thread.Sleep(new Random().Next(1000) + 400);
                }
            }
            catch (Exception)
            {
                updateThread = null;
                statusLabel.Text = "Stopped";
                return;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {

            if (updateThread != null)
            {
                return;
            }
            updateThread = new Thread(xiaoyiMethod);
            statusLabel.Text = "XiaoYi";
            updateThread.Start();
        }

        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            IntPtr ptr = (IntPtr)comboBox3.SelectedItem;
            if (ptr != null && ptr != IntPtr.Zero) {
                pc.target = ptr;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            resetProcess();
        }

        private void logTextBox_TextChanged(object sender, EventArgs e)
        {
            logTextBox.SelectionStart = logTextBox.TextLength;
            logTextBox.ScrollToCaret();
        }
    }
}
